package James.gan.registry.simple;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import james.gan.registry.api.Registry;
import james.gan.registry.api.RegistryCenter;

/**
 * 单版本注册中心
 */
public class MapRegistryCenter extends RegistryCenter {

	private final Logger logger = LoggerFactory.getLogger(MapRegistryCenter.class);
	private static Map<String, List<SocketAddress>> classNameurls = new ConcurrentHashMap<>();
	private static final Map<SocketAddress, Registry> registrys = new ConcurrentHashMap<>();
	private final byte[] byteLock = new byte[0];
	
	@Override
	public void registe(SocketAddress socketAddress, Class<?> clz, Registry registryService) {
		synchronized (byteLock) {
			read();
			String clzJson = JSON.toJSONString(clz);
			Optional.ofNullable(classNameurls.get(clzJson)).orElseGet(() -> {
				List<SocketAddress> list = new ArrayList<>();
				classNameurls.put(clzJson, list);
				return list;
			}).add(socketAddress);
			registrys.put(socketAddress, registryService);
			write();
			logger.debug("Registryed service:[ a:{}| n:{}| c:{}]", socketAddress, registryService.getName(), clz);
		}
	}

	@Override
	public List<SocketAddress> findByClass(Class<?> clz) {
		return classNameurls.get(JSON.toJSONString(clz));
	}

	@Override
	public Registry getRegistry(SocketAddress socketAddress) {
		return registrys.get(socketAddress);
	}

	@Override
	public String getName() {
		return "map";
	}

	@Override
	public Map<Class<?>, List<SocketAddress>> findAll() {
		read();
		Map<Class<?>, List<SocketAddress>> urls = new ConcurrentHashMap<>();
		classNameurls.forEach((k,v)->{
			urls.put(JSON.parseObject(k, Class.class), v);
		});
		return Collections.unmodifiableMap(urls);
	}

	public void read() {
		File file = getFile();
		try (FileInputStream in = new FileInputStream(file);) {
			byte[] b = new byte[(int) file.length()];
			in.read(b);
			String bb = new String(b, "utf-8");
			classNameurls = JSON.parseObject(bb, Map.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void write() {
		try (FileOutputStream out = new FileOutputStream(getFile());) {
			String json = JSON.toJSONString(classNameurls);
			out.write(json.getBytes("utf-8"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private File getFile() {
		return new File("E:\\新建文件夹\\data.json");
	}
	
	public static void main(String[] args) {
		Class<?> c = MapRegistryCenter.class;
		String json = JSON.toJSONString(c);
		System.out.println(json);
		Class parseObject = JSON.parseObject(json, Class.class);
		System.out.println(MapRegistryCenter.class.hashCode());
		System.out.println(parseObject.hashCode());
		System.out.println(MapRegistryCenter.class.equals(parseObject));
		System.out.println(MapRegistryCenter.class.toString());
	}
}
